﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Forms;
using CtefCrmImport.Common;
using CtefCrmImport.Common.Builders;
using CtefCrmImport.Common.Interfaces;
using CtefCrmImport.Common.Operations;
using Microsoft.Crm.Sdk.Samples;
using System.Diagnostics;
using System.Reflection;

namespace CtefCrmImport.Gui
{
    public partial class Form1 : Form
    {
        private CrmRepository rep;
        private ILogger logger;

        public Form1()
        {
            InitializeComponent();
            Initialize();
        }

        private static void ShowSample(string filePath)
        {
            if (!File.Exists(filePath))
            {
                MessageBox.Show("File not found: " + filePath, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Process.Start("notepad.exe", filePath);
        }

        private void Initialize()
        {
            InitializeImportTypes();
            InitializeTargetUrls();
            InitializeContactTypes();

            logger = new StringBufferLogger();
            rep = new CrmRepository(logger);
        }

        private void InitializeImportTypes()
        {
            comboImportType.Items.AddRange(
                new[] { Constants.ImportTypeDonor, Constants.ImportTypeDonationByTransaction, Constants.ImportTypeDonation1, 
                    Constants.ImportTypeDonation2, Constants.ImportTypeStudent, Constants.ImportTypeEmailOnly
                    // , Constants.DeleteInvalidDonors                  /* hidden options */
                });

            comboImportType.SelectedIndex = 0;
        }

        private void InitializeTargetUrls()
        {
            comboTargetUrl.Items.AddRange(
                new[] { 
                    string.Format(CultureInfo.InvariantCulture, Constants.ServerAddressFormat, Constants.SubdomainProduction),
                    string.Format(CultureInfo.InvariantCulture, Constants.ServerAddressFormat, Constants.SubdomainTest)
                });

            comboTargetUrl.SelectedIndex = 0;
        }

        private void InitializeContactTypes()
        {
            comboContactType.Items.AddRange(
                new[] { Constants.ContactTypeStudent, Constants.ContactTypeDonor, Constants.ContactTypeTeacher, Constants.ContactTypeVolunteer });

            comboContactType.SelectedIndex = 0;
        }

        private void buttonValidate_Click(object sender, EventArgs e)
        {
            textSystemOutput.Text = "Validation begins...";
            logger.Reset();
            var config = rep.GetConfig(textUserName.Text, textPassword.Text, (string)comboTargetUrl.Text);
            rep.Validate(config);

            textSystemOutput.Text = logger.GetFullLog();
        }

        private void buttonImport_Click(object sender, EventArgs e)
        {
            // Get username and password.
            string username = textUserName.Text;
            string password = textPassword.Text;
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                MessageBox.Show("Username and password cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textUserName.Focus();
                return;
            }
            
            // Get input file path.
            string inputFilePath = textInputFile.Text;
            if (string.IsNullOrEmpty(inputFilePath) || !File.Exists(inputFilePath))
            {
                MessageBox.Show("No input file or the file does not exists.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textInputFile.Focus();
                return;
            }

            // Get input type.
            string inputType = (string)comboImportType.SelectedItem;

            textSystemOutput.Text = inputType + " import begins...";
            logger.Reset();
            ServerConnection.Configuration config = rep.GetConfig(username, password, (string)comboTargetUrl.SelectedItem);

            try
            {
                if (inputType == Constants.ImportTypeDonor)
                {
                    new ImportDonors(logger, config).Run(inputFilePath);
                }
                else if (inputType == Constants.ImportTypeDonation1)
                {
                    new ImportDonations(logger, config, new DonationBuilder1()).Run(inputFilePath, 1);
                }
                else if (inputType == Constants.ImportTypeDonation2)
                {
                    new ImportDonations(logger, config, new DonationBuilder2()).Run(inputFilePath, 1);
                }
                else if (inputType == Constants.ImportTypeDonationByTransaction)
                {
                    new ImportDonations(logger, config, new DonationByTransaction()).Run(inputFilePath, 2);
                }
                else if (inputType == Constants.ImportTypeStudent)
                {
                    new ImportStudents(logger, config).Run(inputFilePath);
                }
                else if (inputType == Constants.ImportTypeEmailOnly)
                {
                    string contactType = (string)comboContactType.SelectedItem;
                    new ImportEmailsOnly(logger, config, contactType).Run(inputFilePath);
                }
                else if (inputType == Constants.DeleteInvalidDonors)
                {
                    new DeleteDonors(logger, config).DeleteDuplicateDonors();
                }
                else
                {
                    MessageBox.Show("Invalid input type: " + inputType, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                logger.Log("Import error: {0}", ex.Message);
                logger.Log("Error details: {0}", ex.StackTrace);
            }

            textSystemOutput.Text = logger.GetFullLog();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.ShowDialog();
            textInputFile.Text = openFileDialog.FileName;
        }

        private void comboImportType_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get input type.
            string inputType = (string)comboImportType.SelectedItem;
            if (inputType == "Email Only")
            {
                labelContactType.Enabled = true;
                labelContactType.Visible = true;
                comboContactType.Enabled = true;
                comboContactType.Visible = true;
            }
            else
            {
                labelContactType.Enabled = false;
                labelContactType.Visible = false;
                comboContactType.Enabled = false;
                comboContactType.Visible = false;
            }
        }

        private void buttonDisplaySample_Click(object sender, EventArgs e)
        {
            string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SampleData");
            string inputType = (string)comboImportType.SelectedItem;

            if (inputType == Constants.ImportTypeDonor)
            {
                ShowSample(Path.Combine(path, "ImportDonors_sample.txt"));
            }
            else if (inputType == Constants.ImportTypeDonationByTransaction)
            {
                ShowSample(Path.Combine(path, "ImportTypeDonationByTransaction_sample.txt"));
            }
            else if (inputType == Constants.ImportTypeDonation1)
            {
                ShowSample(Path.Combine(path, "ImportDonations_1_sample.txt"));
            }
            else if (inputType == Constants.ImportTypeDonation2)
            {
                ShowSample(Path.Combine(path, "ImportDonations_2_sample.txt"));
            }
            else if (inputType == Constants.ImportTypeStudent)
            {
                ShowSample(Path.Combine(path, "ImportStudents_sample.txt"));
            }
            else if (inputType == Constants.ImportTypeEmailOnly)
            {
                ShowSample(Path.Combine(path, "ImportEmailsOnly_sample.txt"));
            }
            else
            {
                MessageBox.Show("Invalid input type: " + inputType, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
